package middleware;

import javax.tools.*;
import java.net.URI;
import java.util.Iterator;
import java.util.NoSuchElementException;


public class StringJavaCompiler {
    static class JavaSourceFromString extends SimpleJavaFileObject {
        String code;
        
        JavaSourceFromString(String name, String code) {
            super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),
                     Kind.SOURCE);
            this.code = code;
        }
        
        @Override 
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return code;
        }
    }

    public static boolean compileAndLoad(String name, String program) {
        JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
        final JavaSourceFromString jsfs = new JavaSourceFromString(name, program);
        
        if (jc == null) {
            System.err.println("No java compiler found. Check your java.home");
            return false;
        }
        
        Iterable<? extends JavaFileObject> compilationUnits = new Iterable<JavaSourceFromString>() {
            public Iterator<JavaSourceFromString> iterator() {
                return new Iterator<JavaSourceFromString>() {
                    private boolean hasNext = true;
                    
                    public boolean hasNext() {
                        return hasNext;
                    }
                    
                    public JavaSourceFromString next() {
                        if (hasNext) {
                            hasNext = false;
                            return jsfs;
                        } else {
                            throw new NoSuchElementException();
                        }
                    }
                    
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
        
        return jc.getTask(null, null, null, null, null, compilationUnits).call();
    }
}